/**
 * Copyright &copy; 2016-2017 <a href="http://git.oschina.net/whoamien/backend_management">Backend Management</a> All rights reserved.
 */
package com.xw.app.service.impl;

import java.util.Arrays;
import java.util.Collection;
import java.util.List;

import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.xw.app.dao.SysMenuDAO;
import com.xw.app.model.AcctRole;
import com.xw.app.model.SysMenu;
import com.xw.app.service.AcctRoleService;
import com.xw.app.service.SysMenuService;
import com.xw.app.vo.MenuSelection;
import com.xw.framework.base.service.BaseServiceImpl;
import com.xw.framework.vo.UserMenu;
import com.xw.util.ShiroSecurityUtil;
import com.xw.util.StringUtil;

/**
 * The Class SysMenuServiceImpl.
 *
 * @author Xi Wei
 */
@Service
@Transactional
public class SysMenuServiceImpl extends BaseServiceImpl<SysMenu, Long> implements SysMenuService {

	@Autowired
	private SysMenuDAO sysMenuDAO;
	
	@Autowired
	private AcctRoleService acctRoleService;
	
	/* (non-Javadoc)
	 * @see com.xw.app.service.SysMenuService#findByParentIsNull()
	 */
	@Override
	public List<SysMenu> findByParentIsNull() {
		return sysMenuDAO.findBySystemIdAndParentIsNull(ShiroSecurityUtil.getUserSessionInfo().getSystemId());
	}
	
	/**
	 * *
	 * 获取所有可以创建子菜单的菜单项.
	 *
	 * @return the all menu can have sub menu
	 */
	@Override
	public List<UserMenu> getAllMenuCanHaveSubMenu()
	{
		//首先找到所有的顶级节点
		List<SysMenu> topMenuList = sysMenuDAO.findBySystemIdAndMenuLevelLessThanEqual(ShiroSecurityUtil.getUserSessionInfo().getSystemId(),1);
		List<UserMenu> menuTreeList = Lists.newArrayList();
		getMenuSelectionTree(topMenuList, "|-", menuTreeList);
		return menuTreeList;
	}
	
	/**
	 * Gets the menu selection tree.
	 *
	 * @param menuList the menu list
	 * @param prefix the prefix
	 * @param outputList the output list
	 * @return the menu selection tree
	 */
	public void getMenuSelectionTree(Collection<SysMenu> menuList,String prefix,Collection<UserMenu> outputList){
		for(SysMenu menu : menuList){
			UserMenu userMenu = new UserMenu();
			userMenu.setId(menu.getId());
			userMenu.setMenuName(prefix + menu.getMenuName());
			
			outputList.add(userMenu);
			getMenuSelectionTree(menu.getSubMenuList(), "　" + prefix, outputList);
			
		}
	}
	
	/* (non-Javadoc)
	 * @see com.xw.app.service.SysMenuService#GetAllMenuForAssignment(java.lang.Long)
	 */
	@Override
	public List<MenuSelection> GetAllMenuForAssignment(Long roleId){
		//将这一句放在最前面会在循环acctRole.getMenuList时引起Lazy no session 的问题，暂时还不知道怎么回事
		//一种方法是将此语句放在查找AcctRole之后
		//第二种方法是将实体的Lazy属性改成EGAR
		//第三种方法是添加hibernate.enable_lazy_load_no_trans属性为true
		List<SysMenu> allMenus = sysMenuDAO.findBySystemIdAndMenuTypeIn(ShiroSecurityUtil.getUserSessionInfo().getSystemId(),1,2);
		
		List<SysMenu> roleSelectedMenuList = Lists.newArrayList();
		List<Long> selectedMenuIdList = Lists.newArrayList();
		if(roleId != null){
			AcctRole acctRole = acctRoleService.getById(roleId);
			roleSelectedMenuList = acctRole.getMenuList();
			roleSelectedMenuList.forEach(x -> selectedMenuIdList.add(x.getId()));
		}


		List<MenuSelection> menuListForSelection = Lists.newArrayList();
		allMenus.forEach(x -> {
			MenuSelection menu = new MenuSelection();
			try {
				BeanUtils.copyProperties(menu, x);
			} catch (Exception e) {
			}
			if(selectedMenuIdList.contains(x.getId())){
				menu.setChecked(true);
			}
			menuListForSelection.add(menu);
		});
		return menuListForSelection;
	}

	/* (non-Javadoc)
	 * @see com.xw.app.service.SysMenuService#updateMenuForRole(java.lang.String, java.lang.Long)
	 */
	@Override
	
	public void updateMenuForRole(String checkedMenu, Long roleId) {

		if(roleId == null){
			return;
		}
		AcctRole acctRole = acctRoleService.getById(roleId);
		acctRole.setMenuList(Lists.newArrayList());
		acctRoleService.save(acctRole);
				
		if(StringUtil.isNullOrEmpty(checkedMenu)){			
			return;
		}
		
		String[] checkedMenus = checkedMenu.split(",");
		
		Arrays.asList(checkedMenus).forEach(x -> {
			Long id = Long.valueOf(x);
			SysMenu menu = getById(id);
			acctRole.addMenu(menu);
		});
		
		acctRoleService.save(acctRole);
	}

}
